import { Application } from "egg";
import { DaHuaICCBaseService } from "./base";
import { dahua } from "./type";
import CodoError from "../../CodoError";

/**
 * 大华 ICC 卡片管理
 */
export class CardService extends DaHuaICCBaseService {
	constructor(app: Application, config: dahua.icc.ICCConfig) {
		super(app, config);
	}

	/**
	 * 分页查询卡片信息
	 * @param params - 查询参数
	 * @returns 分页数据
	 */
	async queryPage(params: dahua.icc.card.PageQueryParams) {
		const url = `${this.config.baseUrl}/evo-apigw/evo-brm/1.2.0/card/subsystem/page`;
		const res = await this.curl<dahua.icc.IResponse<dahua.icc.IResponse<dahua.icc.card.PageVO<dahua.icc.card.CardInfoVO>>>>(
			url,
			{
				method: "post",
				headers: {
					Authorization: `bearer ${this.accessToken}`,
				},
				contentType: "json",
				dataType: "json",
				data: params,
			}
		);
		this.handleResponseException(res);
		return res.data;
	}

	/**
	 * 生成卡片全局ID
	 * @returns 返回生成的ID
	 */
	async generateOneId(): Promise<dahua.icc.IResponse<dahua.icc.card.AddCardResponse>> {
		const url = `${this.config.baseUrl}/evo-apigw/evo-brm/1.0.0/card/generate-id`;
		const res = await this.curl<dahua.icc.IResponse<dahua.icc.card.AddCardResponse>>(url, {
			method: "get",
			headers: {
				Authorization: `bearer ${this.accessToken}`,
			},
			contentType: "json",
			dataType: "json",
		});
		this.handleResponseException(res);
		return res.data;
	}

	/**
	 * 批量生成卡片全局ID
	 * @param count - 需要生成的ID数量
	 * @returns 返回生成的ID列表
	 */
	async batchGenerateId(count: number): Promise<dahua.icc.IResponse<dahua.icc.card.BatchGenerateIdResponse>> {
		const url = `${this.config.baseUrl}/evo-apigw/evo-brm/1.2.0/card/batch-generate-id`;
		const res = await this.curl<dahua.icc.IResponse<dahua.icc.card.BatchGenerateIdResponse>>(url, {
			method: "get",
			headers: {
				Authorization: `bearer ${this.accessToken}`,
			},
			contentType: "json",
			dataType: "json",
			data: { count },
		});
		this.handleResponseException(res);
		return res.data;
	}

	/**
	 * 新增卡片
	 * @description 新增空白卡/激活卡
	 * @param card - 卡片信息
	 * @param card.id - 主键id，调卡片全局id生成接口获取
	 * @param card.cardNumber - 卡号，8~16位数字字母组合，推荐是8位十六进制数
	 * @param card.cardPassword - 卡密码
	 * @param card.passwordKey - 公钥uuid，和cardPassword同时使用
	 * @param card.category - 卡介质
	 * @param card.cardType - 卡类型
	 * @param card.startDate - 卡片有效期-开始时间，格式yyyy-MM-dd HH:mm:ss
	 * @param card.endDate - 卡片有效期-结束时间，格式yyyy-MM-dd HH:mm:ss
	 * @param card.personId - 人员id
	 * @param card.departmentId - 部门id
	 * @param card.fieldExt - 自定义字段信息
	 * @returns 返回新增的卡片ID
	 */
	async add(card: dahua.icc.card.CardInfo & { id: number }): Promise<dahua.icc.IResponse<dahua.icc.card.AddCardResponse>> {
		const url = `${this.config.baseUrl}/evo-apigw/evo-brm/1.0.0/card/add`;
		const res = await this.curl<dahua.icc.IResponse<dahua.icc.card.AddCardResponse>>(url, {
			method: "post",
			headers: {
				Authorization: `bearer ${this.accessToken}`,
			},
			contentType: "json",
			dataType: "json",
			data: card,
		});
		this.handleResponseException(res);
		return res.data;
	}

	/**
	 * 批量开卡
	 * @param cards - 卡片信息列表
	 * @returns 开卡结果
	 */
	async batchAdd(cards: dahua.icc.card.CardInfo[]): Promise<dahua.icc.IResponse<dahua.icc.card.BatchAddCardResponse>> {
		const url = `${this.config.baseUrl}/evo-apigw/evo-brm/1.0.0/card/batch-add`;
		const res = await this.curl<dahua.icc.IResponse<dahua.icc.card.BatchAddCardResponse>>(url, {
			method: "post",
			headers: {
				Authorization: `bearer ${this.accessToken}`,
			},
			contentType: "json",
			dataType: "json",
			data: {
				cardList: cards,
			},
		});
		this.handleResponseException(res);
		return res.data;
	}
	/**
	 * 更新卡片信息
	 * @description 更新卡片的基本信息，包括卡片有效期、部门、胁迫卡设置等
	 * @param params.cardNumber 卡号，8~16位数字字母组合
	 * @param params.departmentId 部门ID
	 * @param params.isCoercion 是否为胁迫卡(1:是，0：否)
	 * @param params.startDate 卡片有效期开始时间(yyyy-MM-dd HH:mm:ss)
	 * @param params.endDate 卡片有效期结束时间(yyyy-MM-dd HH:mm:ss)
	 * @param [params.cardPassword] 卡密码
	 * @param [params.passwordKey] 公钥uuid
	 * @param [params.availableTimes] 有效次数(仅访客卡)
	 * @param [params.fieldExt] 自定义字段信息
	 * @returns 更新结果，包含更新后的卡片ID
	 */
	async update(params: dahua.icc.card.UpdateCardRequest): Promise<dahua.icc.IResponse<dahua.icc.card.UpdateCardResponse>> {
		const url = `${this.config.baseUrl}/evo-apigw/evo-brm/1.0.0/card/update`;
		const res = await this.curl<dahua.icc.IResponse<dahua.icc.card.UpdateCardResponse>>(url, {
			method: "put",
			headers: {
				Authorization: `bearer ${this.accessToken}`,
			},
			contentType: "json",
			dataType: "json",
			data: params,
		});
		this.handleResponseException(res);
		return res.data;
	}
	/**
	 * 批量删除卡片
	 * @description 删除卡片信息后，卡片相应权限自动删除。注意：卡片状态必须为空白或已注销
	 * @param params 删除参数
	 * @param params.cardIds 卡片ID数组，如[15, 16]
	 * @param params.cardNumbers 卡号数组，如["9836041122"]
	 * @returns 删除结果，包含成功和失败的统计信息
	 * @version v1.0.0
	 * @since ICC V5.0.6
	 * @example
	 * // 通过卡片ID删除
	 * const result = await cardClient.delete({ cardIds: [15, 16] });
	 *
	 * // 通过卡号删除
	 * const result = await cardClient.delete({ cardNumbers: ["9836041122"] });
	 */
	async delete(params: dahua.icc.card.DeleteCardRequest): Promise<dahua.icc.IResponse<dahua.icc.card.DeleteCardResponse>> {
		if (!params.cardIds?.length && !params.cardNumbers?.length) {
			throw new CodoError("cardIds或cardNumbers至少需要提供一个");
		}

		const url = `${this.config.baseUrl}/evo-apigw/evo-brm/1.0.0/card/delete`;
		const res = await this.curl<dahua.icc.IResponse<dahua.icc.card.DeleteCardResponse>>(url, {
			method: "DELETE",
			headers: {
				Authorization: `bearer ${this.accessToken}`,
				"Content-Type": "application/json",
			},
			data: params,
			contentType: "json",
			dataType: "json",
		});

		return res.data;
	}

	/**
	 * 查询卡片详情
	 * @description 根据卡号查询卡片详细信息
	 * @param cardNumber 卡号，8~16位数字字母组合，必须平台唯一
	 * @returns 卡片详情
	 */
	async getDetail(cardNumber: string): Promise<dahua.icc.IResponse<dahua.icc.card.CardInfoVO>> {
		const url = `${this.config.baseUrl}/evo-apigw/evo-brm/1.0.0/card/${encodeURIComponent(cardNumber)}`;
		const res = await this.curl<dahua.icc.IResponse<dahua.icc.card.CardInfoVO>>(url, {
			method: "get",
			headers: {
				Authorization: `bearer ${this.accessToken}`,
			},
			contentType: "json",
			dataType: "json",
		});
		this.handleResponseException(res);
		return res.data;
	}

	/**
	 * 激活卡片（绑定人员）
	 * @description 激活卡片，卡片状态必须为空白
	 * @param params 激活参数
	 * @returns 激活结果，包含卡片ID
	 */
	async active(params: dahua.icc.card.ActiveCardRequest): Promise<dahua.icc.IResponse<dahua.icc.card.ActiveCardResponse>> {
		const url = `${this.config.baseUrl}/evo-apigw/evo-brm/1.0.0/card/active`;
		const res = await this.curl<dahua.icc.IResponse<dahua.icc.card.ActiveCardResponse>>(url, {
			method: "put",
			headers: {
				Authorization: `bearer ${this.accessToken}`,
			},
			contentType: "json",
			dataType: "json",
			data: params,
		});
		this.handleResponseException(res);
		return res.data;
	}

	/**
	 * 换卡/补卡
	 * @description 换卡、补卡 旧卡状态置为已注销、新卡为已激活
	 * @param params 换卡参数
	 * @param params.cardNumber 原有卡号，8~16位数字字母组合
	 * @param params.newCardNumber 新卡号，8~16位数字字母组合
	 * @returns 换卡结果，包含新卡ID
	 */
	async replaceCard(
		params: dahua.icc.card.ReplaceCardRequest
	): Promise<dahua.icc.IResponse<dahua.icc.card.ReplaceCardResponse>> {
		const url = `${this.config.baseUrl}/evo-apigw/evo-brm/1.0.0/card/replace`;
		const res = await this.curl<dahua.icc.IResponse<dahua.icc.card.ReplaceCardResponse>>(url, {
			method: "put",
			headers: {
				Authorization: `bearer ${this.accessToken}`,
			},
			contentType: "json",
			dataType: "json",
			data: params,
		});
		this.handleResponseException(res);
		return res.data;
	}

	/**
	 * 批量退卡
	 * @description 批量退卡接口 - 适用于激活卡，退卡成功后，卡片状态为空白
	 * @param params.cardIds 卡id数组
	 * @returns 退卡结果
	 */
	async returnCards(params: dahua.icc.card.ReturnCardsRequest): Promise<dahua.icc.IResponse<dahua.icc.card.ReturnCardsResponse>> {
		const url = `${this.config.baseUrl}/evo-apigw/evo-brm/1.0.0/card/return`;
		const res = await this.curl<dahua.icc.IResponse<dahua.icc.card.ReturnCardsResponse>>(url, {
			method: "put",
			headers: {
				Authorization: `bearer ${this.accessToken}`,
			},
			contentType: "json",
			dataType: "json",
			data: params,
		});
		this.handleResponseException(res);
		return res.data;
	}
}
